////////////////////////////////////////////////////////////////////////////////////////////////////
/// Copyright (c) 2009 - 2010 RacoonStudios
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this
/// software and associated documentation files (the "Software"), to deal in the Software
/// without restriction, including without limitation the rights to use, copy, modify, merge,
/// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
/// to whom the Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all copies or
/// substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
/// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
/// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
/// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
/// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once
#ifndef queue_h__
#define queue_h__

#include "core/types.h"
#include "Helper/array.h"

namespace Helper
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \class	Queue
	///
	/// \brief	Just a normal queue as you should know it from the STL. Nothing special 
	///			about that.
	///
	///	\todo	Add functions and maybe some documentation.
	///
	/// \author	khaos
	/// \date	02.12.2009
	////////////////////////////////////////////////////////////////////////////////////////////////////
	template<class T>
	class Queue
	{
		public:

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	Queue()
			///
			/// \brief	Default constructor. 
			///
			/// \author	khaos
			/// \date	07.12.2009
			////////////////////////////////////////////////////////////////////////////////////////////////////
			Queue();

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	Queue(const Queue<T> & rhs)
			///
			/// \brief	Constructor. 
			///
			/// \author	khaos
			/// \date	07.12.2009
			///
			/// \param	[in]	rhs	The right hand side object. 
			////////////////////////////////////////////////////////////////////////////////////////////////////
			Queue(const Queue<T> & rhs);




			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void operator= (const Queue<T> & rhs)
			///
			/// \brief	Copy operator. 
			///
			/// \author	khaos
			/// \date	12.12.2009
			///
			/// \param	[in]	rhs	The right hand side object. 
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void operator = (const Queue<T> & rhs);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	bool operator== (const Queue<T> & rhs) const
			///
			/// \brief	Equality operator. 
			///
			/// \author	khaos
			/// \date	12.12.2009
			///
			/// \param	[in]	rhs	The right hand side object. 
			///
			/// \return	True if both objects are equal, otherwise false.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			bool operator == (const Queue<T> & rhs) const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	bool operator!= (const Queue<T> & rhs) const
			///
			/// \brief	Inequality operator. 
			///
			/// \author	khaos
			/// \date	12.12.2009
			///
			/// \param	[in]	rhs	The right hand side object. 
			///
			/// \return	True if both objects are inequal, otherwise false.
			/////////////////////////////////////////////////////////////////////////////////////////////////////
			bool operator != (const Queue<T> & rhs) const;

			



			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void Reserve(tSize size)
			///
			/// \brief	Reserves the specified size.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	size	The size we want to reserve.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void Reserve(tSize size);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	tSize Size() const
			///
			/// \brief	Returns the size of the object.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \return	The objects size.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			tSize Size() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	bool IsEmpty() const
			///
			/// \brief	Determines if this container is empty. 
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \return	True if this container is empty, otherwise false.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			bool IsEmpty() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void Clear()
			///
			/// \brief	Clears this object.
			///
			/// \author	khaos
			/// \date	05.01.2010
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void Clear();

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	bool Contains(const T & element) const
			///
			/// \brief	Determines if this collection contains a given object. 
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	element	The element we are looking for.
			///
			/// \return	True if the specified element is within the container, otherwise false.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			bool Contains(const T & element) const;





			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void Enqueue(const T & element)
			///
			/// \brief	Adds an object onto the end of this queue. 
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	element	The element we want to add.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void Enqueue(const T & element);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	T Dequeue()
			///
			/// \brief	Removes the head object from this queue. 
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \return	The head object from this queue. 
			////////////////////////////////////////////////////////////////////////////////////////////////////
			T Dequeue();

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	T & Peek() const
			///
			/// \brief	Returns the top-of-stack object without removing it. 
			///
			/// \author	khaos
			/// \date	12.12.2009
			///
			/// \return	The current top-of-stack object. 
			////////////////////////////////////////////////////////////////////////////////////////////////////
			T & Peek() const;

		protected:

			Array<T> m_elements;

		private:

	};

}